package xin.xihc.demo.dao;

import org.springframework.beans.factory.annotation.Autowired;
import xin.xihc.jba.core.JbaTemplate;
import xin.xihc.jba.core.PageInfo;
import xin.xihc.jba.demo.BaseModel;

import java.lang.reflect.ParameterizedType;
import java.util.*;

/**
 * 最顶级Dao层,只需继承即可完成基础操作,抽象类
 *
 * @author Leo.Xi
 * @version 1.0
 * @date 2018/9/25 12:53
 * @since 1.0
 */
public class BaseDao<T extends BaseModel> {

    @Autowired
    protected JbaTemplate jbaTemplate;

    /**
     * 返回出去
     *
     * @return
     */
    public JbaTemplate getJbaTemplate() {
        return this.jbaTemplate;
    }

    /**
     * 获取泛型T的Class
     *
     * @return
     */
    @SuppressWarnings("unchecked")
    private Class<T> getTClass() {
        Class<T> tClass = (Class<T>) (((ParameterizedType) this.getClass().getGenericSuperclass())
                .getActualTypeArguments()[0]);
        return tClass;
    }

    /**
     * 添加操作
     *
     * @param record
     * @return
     */
    public boolean add(T record) {
        Objects.requireNonNull(record, "record is null");

        record.setCreateTime(new Date());
        boolean b = jbaTemplate.insertModel(record);
        return b;
    }

    /**
     * 批量添加
     *
     * @param records
     */
    public void batchAdd(T[] records) {
        Objects.requireNonNull(records, "records is null");

        if (records.length < 1) {
            return;
        }

        LinkedList<T> temp = new LinkedList<>();

        for (T record : records) {
            temp.add(record);

            if (temp.size() >= 50) {
                jbaTemplate.insertModels(temp.toArray());
                temp.clear();
            }
        }

        if (temp.size() > 0) {
            jbaTemplate.insertModels(temp.toArray());
        }
        temp.clear();
        temp = null;
    }

    /**
     * 更新操作
     *
     * @param record
     * @return
     */
    public boolean update(T record) {
        Objects.requireNonNull(record, "record is null");
        Objects.requireNonNull(record.getId(), "no id");

        boolean b = jbaTemplate.updateModel(record, "id");
        return b;
    }

    /**
     * 批量执行sql
     *
     * @param sql
     * @param params
     */
    public void batchUpdate(final String sql, Map<String, ?>[] params) {
        jbaTemplate.batchUpdate(sql, params);
    }

    /**
     * 根据ID单个查询
     *
     * @param id
     * @return
     */
    public T findById(final String id) {
        try {
            T t = getTClass().newInstance();
            t.setId(id);
            t = jbaTemplate.queryModelOne(t, getTClass());
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据ID单个查询,返回制定类型
     *
     * @param id
     * @return
     */
    public <E> E findById(final String id, Class<E> clazz) {
        try {
            T t = getTClass().newInstance();
            t.setId(id);
            E e = jbaTemplate.queryModelOne(t, clazz);
            return e;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据ID删除
     *
     * @param id
     * @return
     */
    public boolean deleteById(final String id) {
        T t = null;
        try {
            t = getTClass().newInstance();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        t.setId(id);
        return jbaTemplate.deleteModel(t);
    }

    /**
     * 删除数据
     *
     * @param record
     * @return
     */
    public boolean delete(T record) {
        Objects.requireNonNull(record, "record is null");

        return jbaTemplate.deleteModel(record);
    }

    /**
     * 分页查询
     *
     * @param pageInfo
     * @param record
     * @return
     */
    public List<T> page(T record, PageInfo pageInfo, String... orderBy) {
        Objects.requireNonNull(record, "record is null");
        if (orderBy.length < 1) {
            orderBy = new String[1];
            orderBy[0] = "cid DESC";
        }
        List<T> list = jbaTemplate.queryModelList(record, getTClass(), pageInfo, orderBy);
        return list;
    }

    /**
     * 分页查询
     *
     * @param pageInfo
     * @param record
     * @return
     */
    public <E> List<E> page(T record, Class<E> clazz, PageInfo pageInfo, String... orderBy) {
        Objects.requireNonNull(record, "record is null");
        if (orderBy.length < 1) {
            orderBy = new String[1];
            orderBy[0] = "cid DESC";
        }
        List<E> list = jbaTemplate.queryModelList(record, clazz, pageInfo, orderBy);
        return list;
    }

    /**
     * 查询数量
     *
     * @param record
     * @return
     */
    public int count(T record) {
        Objects.requireNonNull(record, "record is null");

        return jbaTemplate.queryCount(record);
    }

}
